home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 176-200 / disk_190 / nethack / twee.zoo / save.c < prev    next >
C/C++ Source or Header  |  1988-08-04  |  10KB  |  416 lines

  1. /*    SCCS Id: @(#)save.c     2.3     88/01/24
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  
  4. #include <signal.h>
  5. #include <stdio.h>
  6. #include "hack.h"
  7.  
  8. extern char genocided[60];        /* defined in decl.c */
  9. extern char fut_geno[60];        /* idem */
  10. extern struct permonst    pm_wizard;    /* since the wizard evolves */
  11.  
  12. extern char SAVEF[], nul[];
  13. extern char pl_character[PL_CSIZ];
  14. extern long lseek();
  15. extern struct obj *restobjchn();
  16. extern struct monst *restmonchn();
  17.  
  18. dosave(){
  19.     clear_screen();
  20.     fflush(stdout);
  21.     if(dosave0(0)) {
  22.         settty("Be seeing you ...\n");
  23.         exit(0);
  24.     }
  25.     docrt();    /* Redraw screen */
  26. #ifdef LINT
  27.     return(0);
  28. #endif
  29. }
  30.  
  31. #ifndef NOSAVEONHANGUP
  32. hangup(){
  33.     (void) dosave0(1);
  34.     exit(1);
  35. }
  36. #endif
  37.  
  38. /* returns 1 if save successful */
  39. dosave0(hu) int hu; {
  40.     register fd, ofd;
  41.     int tmp;        /* not register ! */
  42. #ifdef DGK
  43.     long fds, needed;
  44.     extern long bytes_counted;
  45.     int mode;
  46. #endif
  47. #ifdef UNIX
  48.     (void) signal(SIGHUP, SIG_IGN);
  49. #endif
  50. #ifndef __TURBOC__
  51.     (void) signal(SIGINT, SIG_IGN);
  52. #endif
  53. #ifdef DGK
  54.     if (!saveDiskPrompt(0))
  55.         return 0;
  56.     fd = open(SAVEF, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FMASK);
  57. #else
  58.     fd = creat(SAVEF, FMASK);
  59. #endif
  60.     if(fd < 0) {
  61.         if(!hu) pline("Cannot open save file. (Continue or Quit)");
  62.         (void) unlink(SAVEF);           /* ab@unido */
  63.         return(0);
  64.     }
  65.     if(flags.moonphase == FULL_MOON)        /* ut-sally!fletcher */
  66.         change_luck(-1);                /* and unido!ab */
  67. #ifdef DGKMOD
  68.     home();
  69.     cl_end();
  70. #endif
  71. #ifdef DGK
  72.     msmsg("Saving: ");
  73.     mode = COUNT;
  74. again:
  75.     savelev(fd, dlevel, mode);
  76.     /* count_only will be set properly by savelev */
  77. #else
  78.     savelev(fd,dlevel);
  79. #endif
  80.     saveobjchn(fd, invent);
  81.     saveobjchn(fd, fcobj);
  82.     savemonchn(fd, fallen_down);
  83.     tmp = getuid();
  84.     bwrite(fd, (char *) &tmp, sizeof tmp);
  85.     bwrite(fd, (char *) &flags, sizeof(struct flag));
  86.     bwrite(fd, (char *) &dlevel, sizeof dlevel);
  87.     bwrite(fd, (char *) &maxdlevel, sizeof maxdlevel);
  88.     bwrite(fd, (char *) &moves, sizeof moves);
  89.     bwrite(fd, (char *) &u, sizeof(struct you));
  90. #ifdef SPELLS
  91.     bwrite(fd, (char *) spl_book, sizeof(struct spell) * (MAXSPELL + 1));
  92. #endif
  93.     if(u.ustuck)
  94.         bwrite(fd, (char *) &(u.ustuck->m_id), sizeof u.ustuck->m_id);
  95.     bwrite(fd, (char *) pl_character, sizeof pl_character);
  96.     bwrite(fd, (char *) genocided, sizeof genocided);
  97.     bwrite(fd, (char *) fut_geno, sizeof fut_geno);
  98. #ifdef HARD
  99.     bwrite(fd, (char *) &pm_wizard, sizeof(struct permonst));
  100. #endif
  101.     savenames(fd);
  102. #ifdef DGK
  103.     if (mode == COUNT) {
  104. #ifdef COMPRESS
  105.         bflush(fd);
  106. #endif
  107.         /* make sure there is enough disk space */
  108.         needed = bytes_counted;
  109.         for (tmp = 1; tmp <= maxdlevel; tmp++)
  110.             if (tmp != dlevel && fileinfo[tmp].where)
  111.                 needed += fileinfo[tmp].size + (sizeof tmp);
  112.         fds = freediskspace(SAVEF);
  113.         if (needed > fds) {
  114.             pline("There is insufficient space on SAVE disk.");
  115.             pline("Require %ld bytes but only have %ld.", needed,
  116.                 fds);
  117.             flushout();
  118.             (void) close(fd);
  119.             (void) unlink(SAVEF);
  120.             return 0;
  121.         }
  122.         mode = WRITE;
  123.         goto again;
  124.     }
  125. #endif
  126.     for(tmp = 1; tmp <= maxdlevel; tmp++) {
  127.         extern int hackpid;
  128. #ifdef DGK
  129.         if (tmp == dlevel || !fileinfo[tmp].where) continue;
  130.         if (fileinfo[tmp].where != ACTIVE)
  131.             swapin_file(tmp);
  132. #else
  133.         extern boolean level_exists[];
  134.  
  135.         if(tmp == dlevel || !level_exists[tmp]) continue;
  136. #endif
  137.         glo(tmp);
  138. #ifdef DGK
  139.         msmsg(".");
  140. #endif
  141.         if((ofd = open(lock, 0)) < 0) {
  142.             if(!hu) pline("Error while saving: cannot read %s.", lock);
  143.             (void) close(fd);
  144.             (void) unlink(SAVEF);
  145.             if(!hu) done("tricked");
  146.             return(0);
  147.         }
  148. #ifdef COMPRESS
  149.         minit();
  150. #endif
  151.         getlev(ofd, hackpid, tmp);
  152.         (void) close(ofd);
  153.         bwrite(fd, (char *) &tmp, sizeof tmp);  /* level number */
  154. #ifdef DGK
  155.         savelev(fd,tmp,WRITE);                  /* actual level */
  156. #else
  157.         savelev(fd,tmp);                        /* actual level */
  158. #endif
  159.         (void) unlink(lock);
  160.     }
  161. #ifdef COMPRESS
  162.     bflush(fd);
  163. #endif
  164.     (void) close(fd);
  165.     glo(dlevel);
  166.     (void) unlink(lock);    /* get rid of current level --jgm */
  167.     glo(0);
  168.     (void) unlink(lock);
  169.     return(1);
  170. }
  171.  
  172. dorecover(fd)
  173. register fd;
  174. {
  175.     register nfd;
  176.     int tmp;        /* not a register ! */
  177.     unsigned mid;        /* idem */
  178.     struct obj *otmp;
  179.     extern boolean restoring;
  180. #ifdef DGK
  181.     struct flag oldflags;
  182.  
  183.     oldflags = flags;    /* Save flags set in the config file */
  184. #endif
  185. #ifdef COMPRESS
  186.     minit();
  187. #endif
  188.     restoring = TRUE;
  189.     getlev(fd, 0, 0);
  190.     invent = restobjchn(fd);
  191.     for(otmp = invent; otmp; otmp = otmp->nobj)
  192.         if(otmp->owornmask)
  193.             setworn(otmp, otmp->owornmask);
  194.     fcobj = restobjchn(fd);
  195.     fallen_down = restmonchn(fd);
  196.     mread(fd, (char *) &tmp, sizeof tmp);
  197. #ifdef WIZARD
  198.     if(!wizard)
  199. #endif
  200.         if(tmp != getuid()) {               /* strange ... */
  201.         (void) close(fd);
  202.         (void) unlink(SAVEF);
  203.         puts("Saved game was not yours.");
  204.         restoring = FALSE;
  205.         return(0);
  206.         }
  207.     mread(fd, (char *) &flags, sizeof(struct flag));
  208. #ifdef DGK
  209.     /* Some config file OPTIONS take precedence over those in save file.
  210.      */
  211.     flags.rawio = oldflags.rawio;
  212.     flags.DECRainbow = oldflags.DECRainbow;
  213.     flags.IBMBIOS = oldflags.IBMBIOS;
  214. #endif
  215.     mread(fd, (char *) &dlevel, sizeof dlevel);
  216.     mread(fd, (char *) &maxdlevel, sizeof maxdlevel);
  217.     mread(fd, (char *) &moves, sizeof moves);
  218.     mread(fd, (char *) &u, sizeof(struct you));
  219. #ifdef SPELLS
  220.     mread(fd, (char *) spl_book, sizeof(struct spell) * (MAXSPELL + 1));
  221. #endif
  222.     if(u.ustuck)
  223.         mread(fd, (char *) &mid, sizeof mid);
  224.     mread(fd, (char *) pl_character, sizeof pl_character);
  225.     mread(fd, (char *) genocided, sizeof genocided);
  226.     mread(fd, (char *) fut_geno, sizeof fut_geno);
  227. #ifdef HARD
  228.     {
  229.     /* Save name pointer from being munged -- tom@uw-warp */
  230.     char *name = pm_wizard.mname;
  231.     mread(fd, (char *) &pm_wizard, sizeof(struct permonst));
  232.     pm_wizard.mname = name;
  233.     }
  234. #endif
  235.     restnames(fd);
  236. #ifdef DGK
  237.     msmsg("\n");
  238.     cl_end();
  239.     msmsg("You got as far as level %d%s.\n", maxdlevel,
  240.         flags.debug ? " in WIZARD mode" : "");
  241.     cl_end();
  242.     msmsg("Restoring: ");
  243. #endif
  244.     while(1) {
  245. #ifdef COMPRESS
  246.         if(mread(fd, (char *) &tmp, sizeof tmp) < 0) /*level #*/
  247. #else
  248.         if(read(fd, (char *) &tmp, sizeof tmp) != sizeof tmp) /*level #*/
  249. #endif
  250.             break;
  251.         getlev(fd, 0, tmp);
  252.         glo(tmp);
  253. #ifdef DGK
  254.         msmsg(".");
  255.         nfd = open(lock, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FMASK);
  256. #else
  257.         nfd = creat(lock, FMASK);
  258. #endif
  259.         if (nfd < 0)    panic("Cannot open temp file %s!\n", lock);
  260. #ifdef DGK
  261.         if (!savelev(nfd, tmp, COUNT | WRITE)) {
  262.  
  263.             /* The savelev can't proceed because the size required
  264.              * is greater than the available disk space.
  265.              */
  266.             msmsg("\nNot enough space on `%s' to restore your game.\n",
  267.                 levels);
  268.  
  269.             /* Remove levels and bones that may have been created.
  270.              */
  271.             (void) close(nfd);
  272.             eraseall(levels, alllevels);
  273.             eraseall(levels, allbones);
  274.  
  275.             /* Perhaps the person would like to play without a
  276.              * RAMdisk.
  277.              */
  278.             if (ramdisk) {
  279.                 /* PlaywoRAMdisk may not return, but if it does
  280.                  * it is certain that ramdisk will be 0.
  281.                  */
  282.                 playwoRAMdisk();
  283.                 (void) lseek(fd, 0L, 0); /* Rewind save file */
  284.                 return dorecover(fd);    /* and try again */
  285.             } else {
  286.                 msmsg("Be seeing you ...\n");
  287.                 exit(0);
  288.             }
  289.         }
  290. #else
  291.         savelev(nfd,tmp);
  292. #endif
  293. #ifdef COMPRESS
  294.         bflush(nfd);
  295. #endif
  296.         (void) close(nfd);
  297.     }
  298.     (void) lseek(fd, 0L, 0);
  299. #ifdef COMPRESS
  300.     minit();
  301. #endif
  302.     getlev(fd, 0, 0);
  303.     (void) close(fd);
  304.     (void) unlink(SAVEF);
  305.     if(Punished) {
  306.         for(otmp = fobj; otmp; otmp = otmp->nobj)
  307.             if(otmp->olet == CHAIN_SYM) goto chainfnd;
  308.         panic("Cannot find the iron chain?");
  309.     chainfnd:
  310.         uchain = otmp;
  311.         if(!uball){
  312.             for(otmp = fobj; otmp; otmp = otmp->nobj)
  313.                 if(otmp->olet == BALL_SYM && otmp->spe)
  314.                     goto ballfnd;
  315.             panic("Cannot find the iron ball?");
  316.         ballfnd:
  317.             uball = otmp;
  318.         }
  319.     }
  320.     if(u.ustuck) {
  321.         register struct monst *mtmp;
  322.  
  323.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  324.             if(mtmp->m_id == mid) goto monfnd;
  325.         panic("Cannot find the monster ustuck.");
  326.     monfnd:
  327.         u.ustuck = mtmp;
  328.     }
  329. #ifndef QUEST
  330.     setsee();  /* only to recompute seelx etc. - these weren't saved */
  331. #endif
  332. #ifdef DGK
  333.     gameDiskPrompt();
  334. #endif
  335.     docrt();
  336.     restoring = FALSE;
  337.     return(1);
  338. }
  339.  
  340. struct obj *
  341. restobjchn(fd)
  342. register fd;
  343. {
  344.     register struct obj *otmp, *otmp2;
  345.     register struct obj *first = 0;
  346.     int xl;
  347. #ifdef LINT
  348.     /* suppress "used before set" warning from lint */
  349.     otmp2 = 0;
  350. #endif
  351.     while(1) {
  352.         mread(fd, (char *) &xl, sizeof(xl));
  353.         if(xl == -1) break;
  354.         otmp = newobj(xl);
  355.         if(!first) first = otmp;
  356.         else otmp2->nobj = otmp;
  357.         mread(fd, (char *) otmp, (unsigned) xl + sizeof(struct obj));
  358.         if(!otmp->o_id) otmp->o_id = flags.ident++;
  359.         otmp2 = otmp;
  360.     }
  361.     if(first && otmp2->nobj){
  362.         impossible("Restobjchn: error reading objchn.");
  363.         otmp2->nobj = 0;
  364.     }
  365.     return(first);
  366. }
  367.  
  368. struct monst *
  369. restmonchn(fd)
  370. register fd;
  371. {
  372.     register struct monst *mtmp, *mtmp2;
  373.     register struct monst *first = 0;
  374.     int xl;
  375.  
  376.     struct permonst *monbegin;
  377.     long differ;
  378.  
  379.     mread(fd, (char *)&monbegin, sizeof(monbegin));
  380. #ifndef MSDOS
  381.     differ = (char *)(&mons[0]) - (char *)(monbegin);
  382. #else
  383.     differ = (long)(&mons[0]) - (long)(monbegin);
  384. #endif
  385.  
  386. #ifdef LINT
  387.     /* suppress "used before set" warning from lint */
  388.     mtmp2 = 0;
  389. #endif
  390.     while(1) {
  391.         mread(fd, (char *) &xl, sizeof(xl));
  392.         if(xl == -1) break;
  393.         mtmp = newmonst(xl);
  394.         if(!first) first = mtmp;
  395.         else mtmp2->nmon = mtmp;
  396.         mread(fd, (char *) mtmp, (unsigned) xl + sizeof(struct monst));
  397.         if(!mtmp->m_id)
  398.             mtmp->m_id = flags.ident++;
  399. #ifndef MSDOS
  400.         mtmp->data = (struct permonst *)
  401.             ((char *) mtmp->data + differ);
  402. #else
  403.         mtmp->data = (struct permonst *)
  404.             ((long) mtmp->data + differ);
  405. #endif
  406.         if(mtmp->minvent)
  407.             mtmp->minvent = restobjchn(fd);
  408.         mtmp2 = mtmp;
  409.     }
  410.     if(first && mtmp2->nmon){
  411.         impossible("Restmonchn: error reading monchn.");
  412.         mtmp2->nmon = 0;
  413.     }
  414.     return(first);
  415. }
  416.